feat(workflows): add isLocked to workflows and folders with cascade lock#4031
feat(workflows): add isLocked to workflows and folders with cascade lock#4031waleedlatif1 wants to merge 3 commits intostagingfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryMedium Risk Overview Enforces lock semantics end-to-end: APIs now restrict updates/deletes on locked resources (admin required to toggle Updates workflow diffing to ignore block-level Reviewed by Cursor Bugbot for commit de71cd7. Configure here. |
Greptile SummaryThis PR introduces an Key changes:
Issues found:
Confidence Score: 4/5Not safe to merge as-is: folder-level lock can be bypassed via direct API calls on child workflows, and locked items can still be duplicated from the sidebar. Two P1 issues exist: (1) the server-side workflow DELETE/PUT guards only check the workflow's own
|
| Filename | Overview |
|---|---|
| apps/sim/app/api/workflows/[id]/route.ts | Adds isLocked to the UpdateWorkflow schema and guards DELETE/PUT with 403; critical gap: checks only workflowData.isLocked, missing the server-side folder-cascade walk. |
| apps/sim/app/api/folders/[id]/route.ts | Adds isLocked to folder schema, correctly gates admin-only lock toggle and blocks non-expand mutations + DELETE on locked folders. |
| apps/sim/hooks/use-effective-lock.ts | New hook correctly walks the folder parent chain to compute effective lock state for both workflows and folders. |
| apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/workflow-item/workflow-item.tsx | Adds lock icon, handleToggleLock, and disables rename/color/delete correctly; but disableDuplicate is missing the isEffectivelyLocked guard, allowing duplication of locked workflows. |
| apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/folder-item/folder-item.tsx | Adds lock icon and toggle for folders with correct rename/delete/create guards; same disableDuplicate gap as workflow-item — missing isEffectivelyLocked check. |
| packages/db/migrations/0187_certain_pretty_boy.sql | Safe migration: adds is_locked boolean DEFAULT false NOT NULL to both workflow and workflow_folder tables; no data risk. |
| apps/sim/lib/workflows/comparison/compare.test.ts | Adds a regression test confirming that toggling block-level locked does not flip the deploy-badge diff; correctly validates existing behavior. |
| apps/sim/hooks/queries/folders.ts | Adds isLocked to mapFolder, UpdateFolderVariables, and the optimistic create/duplicate folder payloads; correctly defaults to false. |
| packages/db/schema.ts | Adds isLocked: boolean('is_locked').notNull().default(false) to both workflow and workflowFolder Drizzle table definitions; correct and consistent. |
| apps/sim/hooks/queries/utils/workflow-list-query.ts | Adds isLocked to WorkflowApiRow and maps it through mapWorkflow with a safe ?? false default. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[User action: rename / delete / duplicate / move] --> B{Client-side\nisEffectivelyLocked?}
B -- Yes --> C[Block action in UI\nrename/delete/color/move disabled]
B -- No --> D[Allow action → API call]
D --> E{API route\nworkflowData.isLocked?}
E -- true --> F[Return 403]
E -- false --> G[Execute mutation ✓]
H[Folder locked\nworkflow.isLocked = false] -.->|Cascade walk\nclient-side only| B
H -.->|NOT checked\nserver-side| E
style H fill:#ffd6d6,stroke:#cc0000
style E fill:#ffd6d6,stroke:#cc0000
style G fill:#d4edda,stroke:#28a745
Reviews (1): Last reviewed commit: "feat(workflows): add isLocked to workflo..." | Re-trigger Greptile
...Id]/w/components/sidebar/components/workflow-list/components/workflow-item/workflow-item.tsx
Outdated
Show resolved
Hide resolved
...paceId]/w/components/sidebar/components/workflow-list/components/folder-item/folder-item.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit de71cd7. Configure here.
…ock support Add first-class `isLocked` property to workflows and folders that makes locked items fully read-only (canvas, sidebar rename/color/move/delete). Locked folders cascade to all contained workflows and sub-folders. Lock icon shown in sidebar, admin-only toggle via context menu. Coexists with block-level `locked` for granular protection. Also excludes block-level `locked` from diff detection so locking no longer flips deploy status. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…urity gaps - Split lock utilities into pure functions (lock.ts) and DB-backed functions (lock-db.ts) - Add cascade lock checks to all API routes: workflow CRUD, folder CRUD, state save, reorder/move - Add workflow lock check to Socket.IO collaborative operations - Block drag-and-drop for locked items and into locked folders - Fix lock bypass when isLocked is included alongside other fields in request body - Disable duplicate action for locked workflows and folders - Make isLocked required in WorkflowMetadata type (matches NOT NULL schema) - Add 16 unit tests for lock utility functions - Re-export pure functions from hooks/use-effective-lock.ts for client compatibility Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
de71cd7 to
5716bf0
Compare
- Fix infinite loop in pure isFolderEffectivelyLocked on circular parentId chains - Add lock checks to create/duplicate routes (block writes into locked folders) - Use isWorkflowEffectivelyLockedDb instead of inline checks in state/workflow routes - Remove use-effective-lock.ts re-export file; import from @/lib/workflows/lock directly - Remove dead import and re-export from lock-db.ts - Use LockableFolder type in reorder routes - Add test for all-unlocked circular chain edge case Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Summary
isLockedboolean column toworkflowandworkflow_foldertables with safe NOT NULL DEFAULT false migrationisLockedlockedfrom diff detection so locking no longer flips deploy badge from "Live" to "Update"lockedfor granular protection within unlocked workflowsTest plan
ALTER TABLE ADD COLUMNstatements execute cleanlybun run lintpasses🤖 Generated with Claude Code